#include "httpserver.h"
#include <functional>
#include "Utils/tcpconnection.h"
#include "httpcontent.h"

using namespace tiny_muduo;

HttpServer::HttpServer(EventLoop* loop, const Address& address)
    :loop_(loop),
    server_(loop, address)
{
    server_.SetConnectionCallback(std::bind(&HttpServer::ConnectionCallback, this, std::placeholders::_1, std::placeholders::_2));
    server_.SetMessageCallback(std::bind(&HttpServer::MessageCallback, this, std::placeholders::_1, std::placeholders::_2));
    server_.SetThreadNums(kThreadNums);

    loop_->RunEvery(3.0, std::bind(&HttpServer::TestTimer_IntervalEvery3Seconds, this));
    loop_->RunAfter(10.0, std::bind(&HttpServer::TestTimer_IntervalEvery10Seconds, this));

    // 默认，可以用Set修改
    SetHttpResponseCallback(std::bind(&HttpServer::HttpDefaultCallback, this, std::placeholders::_1, std::placeholders::_2));
}

HttpServer::~HttpServer()
{}

void HttpServer::MessageCallback(const TcpConnectionPtr& connection, Buffer* buffer)
{
    if(connection->IsShutdown()) return;

    HttpContent* content = connection->GetHttpContent();
    if(!content->ParseContent(buffer))
    {
        connection->Send("HTTP/1.1 400 Bad Request\r\n\r\n");
        connection->Shutdown();
    }

    if(content->IsCompleteRequest())
    {
        DealWithRequest(content->request(), connection);
        content->ResetContentState();
    }
}

void HttpServer::DealWithRequest(const HttpRequest& request, const TcpConnectionPtr& connection)
{
    std::string connection_state = std::move(request.GetHeader("Connection"));
    bool close = (connection_state == "Close" || (request.version() == kHttp10 && connection_state != "Keep-Alive"));

    HttpResponse response(close);

    response_callback_(request, response);

    Buffer buffer;
    response.AppendToBuffer(&buffer);
    connection->Send(&buffer);

    if(response.CloseConnection())
    {
        connection->Shutdown();
    }
}
